`timescale 1ns/1ps

module tb_datin_bram;

  // 时钟和复位
  reg work_clk_300m;
  reg rst_n;

  initial begin
    work_clk_300m = 0;
    forever #1.667 work_clk_300m = ~work_clk_300m; // 300MHz ≈ 3.33ns周期，1.667ns一半
  end

  // DUT接口信号
  reg         datin_bram_w_en;
  reg         datin_bram_w_we;
  reg  [10:0]  datin_bram_w_addr;
  reg  [9:0]  datin_bram_w_data;

  reg         datin_bram_r_en;
  reg  [10:0]  datin_bram_r_addr;
  wire [9:0]  datin_bram_r_data;

  // 实例化 DUT
  datin_bram u_datin_bram (
    .clka(work_clk_300m),
    .ena(datin_bram_w_en),
    .wea(datin_bram_w_we),
    .addra(datin_bram_w_addr),
    .dina(datin_bram_w_data),
    .clkb(work_clk_300m),
    .enb(datin_bram_r_en),
    .addrb(datin_bram_r_addr),
    .doutb(datin_bram_r_data)
  );

  // 测试过程
  integer i;

  initial begin
    // 初始化
    datin_bram_w_en   = 0;
    datin_bram_w_we   = 0;
    datin_bram_w_addr = 0;
    datin_bram_w_data = 0;
    datin_bram_r_en   = 0;
    datin_bram_r_addr = 0;

    // 上电复位
    rst_n = 0;
    #10 rst_n = 1;

    // 写入过程
    @(posedge work_clk_300m);
    for (i = 0; i < 16; i = i + 1) begin
      @(posedge work_clk_300m);
      datin_bram_w_en   <= 1;
      datin_bram_w_we   <= 1;
      datin_bram_w_addr <= i[10:0];
      datin_bram_w_data <= i[9:0];
    end

    // 结束写入
    @(posedge work_clk_300m);
    datin_bram_w_en   <= 0;
    datin_bram_w_we   <= 0;

    // 等待两拍
    repeat (2) @(posedge work_clk_300m);

    // 开始循环读取
    for (i = 0; i < 32; i = i + 1) begin
      @(posedge work_clk_300m);
      datin_bram_r_en   <= 1;
      datin_bram_r_addr <= i[3:0]; // 循环访问0~15
      $display("Read Addr: %0d, Data: %0d", i[3:0], datin_bram_r_data);
    end

    // 结束
    @(posedge work_clk_300m);
    datin_bram_r_en <= 0;

    #20 $finish;
  end

endmodule
